/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2018.5.8 类的具体实现代码编写

 ***************************************************************************
 *  @file ultrasonicsensor.h
 *  功能: 超声波传感器的设置和数据获取
 *
 *                                                                         *
 ***************************************************************************/

#ifndef ULTRASONICSENSOR_H
#define ULTRASONICSENSOR_H
#include <QString>
#include <QMap>
#include <wchar.h>
#include <QVector>
#include <QTimer>
#include <qobject.h>
#include <QMutex>
#include <QList>
#include "MacroDefine/globalDefine.h"
//#include  "gSoapFoundation/soapStub.h"

class QSerialPort;
struct SerialPortConfig_ultrasonic;

#define IF_DEBUG         (1)    //控制是否打印调式信息宏开关

/**
  * @brief 超声波传感器探测返回数据范围 (单位:mm)
  */
#define MIN_DETECT         (10)
#define MAX_DETECT         (5200)

// 超声波传感器探测最大耗时     (单位:ms)
#define DETECT_MAX_TIME_CONSUMING   (87)

/**
 * @brief The EM_POWER_NOISE_CLASS enum  降噪电源级别
 */
enum EM_POWER_NOISE_CLASS
{
    EM_POWER_NOISE_CLASS_1,//电池供电，超声波波束角度较大，精度高
    EM_POWER_NOISE_CLASS_2,
    EM_POWER_NOISE_CLASS_3,//USB供电
    EM_POWER_NOISE_CLASS_4,//开关电源供电
    EM_POWER_NOISE_CLASS_5,
    EM_POWER_NOISE_CLASS_6,//大噪音开关电源供电，超声波波束角度较小，精度差

};

/**
 * @brief The UltrasonicDeviceNode struct ，超声波配置文件设备节点属性
 */
struct UltrasonicDeviceNode
{
    unsigned int deviceId;
    EM_POWER_NOISE_CLASS powerNoiseClass;
    int datectRange;
    int location;

};


/**
 * @brief The UltrasonicSensor class, 超声波传感器的参数配置和数据获取
 */
class UltrasonicSensor:public QObject
{
    Q_OBJECT
public:

    /**
     * @brief UltrasonicSensor          构造函数
     * @param configFilePath            超声波传感器配置文件路径
     */
    UltrasonicSensor(QString configFilePath);

public:
    int setDebugFlag(int debugFlagIn);
    /**
     * @brief setNewCollisionParameter
     * @param barrierSlowDownDistanceIn 单位ｍ
     * @param barrierSlowDownRatioIn 单位ｍ
     * @param barrierStopDistanceIn 单位ｍ
     * @return
     */
    int setNewCollisionParameter( double barrierSlowDownDistanceIn,double barrierSlowDownRatioIn,
                                                        double barrierStopDistanceIn);
    int setUltrasonicSensorCheckEnable(bool isOn);
    int getUltrasonicSensorSafeStatus(std::vector<double> &safeStatusOut,bool &isCheckEnableOut);
    /**
     * @brief isInitialOkStatus         KS103-485 初始化配置文件状态
     * @return                          success:true  failed:false
     */
    bool isInitialOkStatus();

    int ultrasonicSensorProtectLoop(E_BARRIER_TETECT_MODE validModeIn, double &safeSpeedRatioOut);

    int setSensorWork(int locationIn,bool isEnable);


    /**
     * @brief setSensor485Address       设置传感器RS485地址
     * @param origineAddressIn          原地址
     * @param addressIn                 目标地址
     * @return                          success: 1  failed: -1
     */
    int setSensor485Address(int origineAddressIn, int addressIn);

    /**
     * @brief setPowerSupplyNoiseClass      设置电源降噪级别
     * @param deviceId                      超声波传感器设备ID
     * @param classIn                       电源降噪级别
     * @return                              success: 1  failed: -1
     */
    int setPowerSupplyNoiseClass(int devicdId, EM_POWER_NOISE_CLASS classIn);


    int setUltrasonicPowerSupplyNoiseClass(EM_POWER_NOISE_CLASS classIn);
    /**
     * @brief setDetectDistanceRange           设置超声波传感器探测范围
     * @param deviceId                         超声波传感器设备ID
     * @param detectRangeIn,unit is mm         探测范围
     * @return                                 1=sucess, -1=failed
     */
    int setDetectDistanceRange(int devicedId, double detectRangeIn);

    /**
     * @brief getDetectDistanceFromBuffer       从缓存中获取探测数据
     * @param deviceId                          超声波传感器设备ID
     * @param distanceResultOut ,unit is mm     探测数据
     * @return                                  1=sucess, -1=failed
     */
    int getDetectDistanceFromBuffer(int devicdId, double &distanceResultOut);

    /**
     * @brief getDetectDistanceFromBuffer       从缓存中获取探测数据
     * @param distanceResultOut                 缓存探测数据容器
     * @return
     */
    int getDetectDistanceFromBuffer(QVector<double> &distanceResultOut);

    /**
     * @brief getDetectDistanceFromBuffer       从缓存中获取探测距离
     * @param locationIn                        位置
     * @param distanceResultOut                 探测数据容器
     * @return
     */
    int getDetectDistanceFromBuffer(int locationIn,QVector<double> &distanceResultOut);

    int getSensorName(std::vector<std::string> &sensorNames);

    /**
     * @brief getSensorStatus                   获取传感器状态
     * @param deviceRequestCountOut             设备请求数量容器
     * @return                                  success : 1
     */
    int getSensorStatus(QVector< int> &deviceRequestCountOut);

    /**
     * @brief isAllSensorRequestResponseOk      查看传感器的请求得到应答
     * @param deviceIdOut                       超声波传感器设备ID
     * @return                                  1=sucess, -1=failed
     */
    int isAllSensorRequestResponseOk(int &deviceIdOut);

    /**
     * @brief updateAllSensorDistanceValue 本函数需要周期性调用，来更新sensorDistanceValue，接
     * 收上次的数据，然后发送获取命令
     * @return                              1=sucess, -1=failed
     */
    int updateAllSensorDistanceValue();



private slots:

    /**
     * @brief timeOut_slot              计时器响应槽函数
     */
    void timeOut_slot();

private:
    int getLocationSensorSafeRatioOutput(int locationIn, double &safeSpeedRatioOut);
    /**
     * @brief initialSensorByConfigFile     初始化超声波传感器配置文件
     * @param configFilePath                超声波传感器配置文件路径
     * @return                              1 : sucess, 0> :failed
     */
    int initialSensorByConfigFile(QString configFilePath);

//    int readCollisionConfigFile(QString configFilePathIn,SafeCollisionInfo &collisionInfoOut);

    /**
     * @brief initalSerial                  初始化串口
     * @return                              1=sucess, -1=failed
     */
    int initalSerial();

    /**
     * @brief sendGetValueCommand           发送获取探测数据指令
     * @param deviceId                      接收指令的设备ID
     * @return                              1:success
     */
    int sendGetValueCommand(int deviceId);

    void addMsg( int messageLevel,
                 std::string componentName,
                 std::string messageType,
                 int messageCode,
                 int robotId,
                 int parameter1 = 0,
                 int parameter2 = 0,
                 int parameter3 = 0,
                 int parameter4 = 0 );

    /**
     * @brief isOneDeviceRequestResponseOk  查看一个设备的请求是否应答
     * @param deviceIdIn                    设备id
     * @return                              1=sucess, -1=failed
     */
    int isOneDeviceRequestResponseOk(int deviceIdIn);


private slots:

    /**
     * @brief receiveDetectData             接收探测数据
     * @return
     */
    int receiveDetectData();

private:

    /**
     * @brief sensorEnable          传感器使能状态列表
     */
    QMap<int, bool> sensorEnable;

    /**
     * @brief sensorDistanceValue   超声波传感器探测数据缓存
     */
    QMap<int, double> sensorDistanceValue;

    /**
     * @brief deviceNodeMap         保存设备节点参数
     */
    QMap<int, UltrasonicDeviceNode> deviceNodeMap;

    /**
     * @brief it                    保存设备节点参数迭代器对象
     */
    QMap<int, UltrasonicDeviceNode>::const_iterator iterator_currentNode;

    /**
     * @brief deviceRequestCount    设备请求数量
     */
    QMap<int, int> deviceRequestCount;

    /**
     * @brief serialConfig          保存配置文件中的串口配置数
     */
    SerialPortConfig_ultrasonic *serialConfig;

    /**
     * @brief deviceNode            超声波配置文件设备节点属性
     */
    UltrasonicDeviceNode *deviceNode;

    /**
     * @brief timer                 计时器
     */
    QTimer timer;

    /**
     * @brief isInitialOk           配置文件初始化状态
     */
    bool isInitialOk;

    /**
     * @brief serialPort            串口对象
     */
    QSerialPort *serialPort_device;


    /**
     * @brief mutex                 mutex同步锁
     */
    QMutex mutex;

    /**
     * @brief validAddressList      有效地址数组
     */
    QList <int> validAddressList;

//    SafeCollisionInfo collisionInfo;

    double barrierSlowDownDistance; //单位ｍm
    double barrierSlowDownRatio;
    double barrierStopDistance; //单位ｍm

    bool isDetectEnable;

    std::vector<double> sensorSafeStatus;//1 2 3 4支持４个方位，其它暂时不支持
    int debugFlag;

};

#endif // ULTRASONICSENSOR_H
